// c++ version of CWFC
#include <algorithm>
#include <array>
#include <cmath>
#include <limits>
#include <memory>
#include <numeric>
#include <random>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <chrono>
#include <opencv2/core/utility.hpp>
#include <opencv2/opencv.hpp>
#include <sys/shm.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <unistd.h>
#include <math.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <vector>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>

#include <iostream>
#include <ctime>
// // #include <thrust/host_vector.h>
// #include <thrust/device_vector.h>
// #include <thrust/generate.h>
// #include <thrust/sort.h>
// #include <thrust/copy.h>

using namespace cv;
using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// define data structures and global variables
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int width = 8;
int height = 8;
vector<vector<double>> entropy;
vector<int> candidates = {1,2,3,4,5,6,7,8,9,10,11,12,13};
vector<int> candidates_X_symmetry = {1,2,3,4,5};
map<int,int> candidates_X_symmetry_map;

vector<vector<int>> rules = {
    {1,0,2,0},
    {2,0,3,0},
    {3,0,4,0},
    {4,0,5,0},
    {5,0,4,0},
    {4,0,3,0},
    {3,0,2,0},
    {2,0,1,0},
    {1,0,1,0},
    {2,0,2,0},
    {3,0,3,0},
    {4,0,4,0},
    {5,0,5,0},

    {6,0,1,0},
    {2,0,6,0},
    {1,0,6,0},
    {6,0,2,0},

    {7,0,2,0},
    {3,0,7,0},
    {2,0,7,0},
    {7,0,3,0},

    {8,0,3,0},
    {4,0,8,0},
    {3,0,8,0},
    {8,0,4,0},

    {9,0,4,0},
    {5,0,9,0},
    {4,0,9,0},
    {9,0,5,0},

    {2,0,10,0},
    {10,0,1,0},
    {1,0,10,0},
    {10,0,10,0},
    {10,0,1,0},

    {3,0,11,0},
    {11,0,2,0},
    {2,0,11,0},
    {11,0,11,0},
    {11,0,2,0},

    {4,0,12,0},
    {12,0,3,0},
    {3,0,12,0},
    {12,0,12,0},
    {12,0,3,0},

    {5,0,13,0},
    {13,0,4,0},
    {4,0,13,0},
    {13,0,13,0},
    {13,0,4,0}
};


vector<vector<int>> rules0 = {
    {1,0,2,0},
    {2,0,3,0},
    {3,0,4,0},
    {4,0,5,0},
    {5,0,4,0},
    {4,0,3,0},
    {3,0,2,0},
    {2,0,1,0},
    {1,0,1,0},
    {2,0,2,0},
    {3,0,3,0},
    {4,0,4,0},
    {5,0,5,0}
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// define functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

bool inline find_in_vector(vector<int> &v, int k) {
    for(int i=0;i<v.size();i++) {
        if(v[i] == k) {
            return true;
        }
    }
    return false;
}

bool inline find_element(vector<vector<int>> &v, vector<int> k) {
    for(int i=0;i<v.size();i++) {
        
        if(v[i] == k) {
            return true;
        }
    }
    return false;
}

int main()
{
    set<int> result;
    int res = 0;
    // measure time consumption
    auto start = std::chrono::system_clock::now();

    for(int j=0;j<100000;j++)
        for(int i=0;i<rules0.size();i++)
        {
            if(find_element(rules,rules0[i]))
            {
                res++;
            }
        }

    auto end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end-start;
    std::time_t end_time = std::chrono::system_clock::to_time_t(end);
    std::cout << "finished computation at " << std::ctime(&end_time)
              << "elapsed time: " << elapsed_seconds.count() << "s\n";

    // print result
    cout<<"result size: "<<res<<endl;
    // for(auto it=result.begin();it!=result.end();it++)
    //     cout<<*it<<endl;
    
    return 0;
}
